<?php

/**
 * Project: Espolon
 * Licence: BSD License
 * Link: http://espolon.org/
 * Copyright: Nicolas de Bari Embriz Garcia Rojas <nbari at espolon dot org>
 * Author: Nicolas de Bari Embriz Garcia Rojas <nbari at espolon dot org>
 * Version: Beta
 */

if (!defined('SITE_ROOT')) exit('No direct script access allowed');

class Dispatcher {
  private $db;
  private $tpl;
  private $sess;
  private $config;
  private $template;
  private $uri;
  private $module;
  private $command;
  private $options;
  private $perms = null;
  private $is_admin = false;

  function __construct() {
    /**
     *  begin ADODB
     */
    $this->db = ADONewConnection(DSN);
    $this->db->debug = ADODB_DEBUG;
    $this->db->Execute('SET NAMES UTF8');  #mb_unserialize
    # $this->db->SetFetchMode(ADODB_FETCH_ASSOC);

    /**
     *  Get and set some defaults values from config
     */
    $this->config = $this->db->CacheGetAssoc("SELECT * FROM core_config");
    $this->template = $this->config['site_theme'];

    /**
     * Gettext
     */
    $lang = ($this->config['site_language'] == 'Browser Language') ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : $this->config['site_language'];
    if (!is_dir(SITE_ROOT."locale/$lang")) {
      foreach(scandir(SITE_ROOT.'locale') as $locale) {
        if (preg_match('/^'.substr($lang, 0,2).'/i', $locale)) {
          $lang = $locale;
        }
      }
    }

    putenv("LANG=$lang");
    setlocale(LC_ALL, $lang.'.UTF-8');
    bindtextdomain('messages', SITE_ROOT.'locale');
    textdomain('messages');

    /**
     *  begin SMARTY
     */
    $this->tpl = new CMS();
    $this->tpl->assign('template',$this->template);
    $this->tpl->config_load('errors.conf');

    /**
     *  Proccess URI
     */
     # $this->uri = preg_split("/\//i", strip_tags($_SERVER["REQUEST_URI"]), -1, PREG_SPLIT_NO_EMPTY);
    $this->uri = preg_split("/\//i", urldecode($_SERVER["REQUEST_URI"]), -1, PREG_SPLIT_NO_EMPTY);
    $this->module = (!empty($this->uri) && is_dir(SITE_ROOT.'modules/'.$this->uri[0])) ? array_shift($this->uri) :  $this->config['default_module'];
  }

  function getDb() { return $this->db; }
  function getTpl() { return $this->tpl; }
  function getSess() { return $this->sess; }
  function getTemplate() { return $this->template; }
  function getModule() { return $this->module; }
  function getCommand() { return urldecode($this->command[0]); }
  function getOptions() { return $this->options; }
  function getConfig($value=null) { return $this->config[$value]; }
  function getPerms($module=null) { return (isset($module)) ? $this->perms[$module] : $this->perms; }

  function checkPerms () {
    $uid = sess_get('uid') ? sess_get('uid') : 0;
    switch($uid) {
      case ($uid != 1):
      $rids = $this->db->CacheGetCol("SELECT rid FROM core_users_roles WHERE uid=$uid");
      if(!$rids) {
        $perms = ($rs = $this->db->CacheGetOne("SELECT perms FROM core_permissions WHERE rid=2")) ? unserialize($rs) : array();
      } else {
        if (in_array(3, $rids)) {
          $perms = ($rs = $this->db->CacheGetOne("SELECT perms FROM core_permissions WHERE rid=3")) ? unserialize($rs) : null;
          $this->is_admin = true;
        } else {
          $perms = array();
          foreach ($rids as $rid) {
            $permissions = unserialize($this->db->CacheGetOne("SELECT perms FROM core_permissions WHERE rid=$rid AND rid != 3"));
            if (!empty($permissions)) {
              $perms = array_merge_recursive($permissions, $perms);
            }
          }
        }
      }
      break;
      case 1:
        $perms = ($rs = $this->db->CacheGetOne("SELECT perms FROM core_permissions WHERE rid=3")) ? unserialize($rs) : null;
        $this->is_admin = true;
      break;
      default:
        $perms = ($rs = $this->db->CacheGetOne("SELECT perms FROM core_permissions WHERE rid=1")) ? unserialize($rs) : null;
      break;
    } // end of switch

    if ($perms) {
      foreach ($perms as $key=>$value ) {
        $perms[$key] = array_unique($value);
      }
      $active_modules = array_keys($perms);
      asort($active_modules);

      $module_groups = array();
      foreach ($this->db->CacheGetAll("SELECT id, name FROM core_module_groups ORDER BY rank") as $value) {
        foreach(array_keys($perms) as $mod) {
          $rs = $this->db->CacheGetRow("SELECT t1.name, t2.rank FROM core_module_groups_modules t2 LEFT JOIN core_modules t1 ON t1.id=t2.mid WHERE t2.gid=$value[id] AND t1.name='$mod'");
          if($rs) {
            $module_groups[$value['name']][$rs['rank']] = $mod;
          }
        }
        ksort($module_groups[$value['name']]);
      }
    }

    $this->perms = $perms;
    $this->tpl->assign('perms', $perms);
    $this->tpl->assign('active_modules', empty($perms) ? null : $active_modules);
    $this->tpl->assign('module_groups', empty($module_groups) ? null : $module_groups);
    $this->tpl->assign('is_admin', $this->is_admin);

    /**
     * set command and options
     */
    $default_command = ($dc = empty($this->config['default_command_'.$this->module]) ? null : $this->config['default_command_'.$this->module]) ? (@in_array($dc, $this->getPerms($this->module)) ? $dc : null) : null;
    $this->command = empty($this->uri) ? array($default_command) : $this->uri;
    $this->options = (count($this->command) > 1) ? array_slice($this->command, 1) : null;
  } //end of check_perms

  private function is_admin() {
    return $this->is_admin ? true : sign_out();
  }

  /**
   * Remember me option
   */
  function rmb () {
    if(!sess_get('uid') AND isset($_COOKIE['rmb'])) {
      list($uid,$hash,$token) = unserialize(base64_decode($_COOKIE['rmb']));
      $rs = $this->db->GetRow("SELECT * FROM core_users WHERE uid='$uid' AND cookie='$token'");
      if (!$rs) {
        sign_out();
      } elseif (sha1($_SERVER['HTTP_ACCEPT_LANGUAGE'].$_SERVER['HTTP_USER_AGENT']) == $hash ) {
        sess_set('uid', $rs['uid']);
        sess_set('login', $rs['login']);
        sess_set('login_ip', $rs['login_ip']);
        sess_set('login_host', $rs['login_host']);
        sess_set('login_date', $rs['login_date']);
        sess_set('login_count', $rs['login_count']);
      }
    }
  }

  function checkAccess($module = null, $command = null) {
    if (sess_get('uid') != 1) {  // if not admin check perms
      if(!@array_key_exists($module, $this->getPerms())) {
        sign_out($this->sess);
      } elseif (!empty($command) AND !in_array($command, $this->getPerms($module))) {
        sign_out($this->sess);
      }
    }
    $rs = $this->db->GetOne("SELECT status FROM core_modules WHERE name='$module'");
    $this->tpl->assign('module_off', ($rs == 1) ? false : true);
  }

  function dispatch() {
    $db = $this->getDb();
    $tpl = $this->getTpl();
    $sess = $this->getSess();
    $template = $this->getTemplate();
    $module = $this->getModule();
    $command = $this->getCommand();
    $options = $this->getOptions();
    $module_tpl = $this->getModule().'.tpl';
    $path = is_array($options) ? implode('/', $options) : null;
    $fullpath = (empty($command)) ? "$module" : "$module/$command/$path";
    $tpl->assign('sname', $this->getconfig('site_name'));
    $tpl->assign('slogan', $this->getConfig('site_slogan'));
    $tpl->assign('path', urldecode($fullpath));
    $tpl->assign('module', $module);
    $tpl->assign('command', $command);
    $tpl->assign('display_all_modules', ($this->getConfig('display_all_modules') == 1) ? true : false);
    require_once SITE_ROOT.'modules/'.$this->getModule().'/'.$this->getModule().'.php';
  }

} // end of class

?>